/*
 * @Author: ZARR 
 * @Date: 2018-05-09 22:35:17 
 * @Last Modified by: ZARR
 * @Last Modified time: 2018-05-14 14:24:44
 * 实现对文章的增删改查并且提示错误
 */

import { article as articleModel, type as articleTypeModel} from '../models/Article'
import chalk from 'chalk'
import {error} from 'util'
import { throws } from 'assert';

class Article {

    constructor() { //构造函数
        this.articleParams = []
        this.articleParamsError = ['标题', '描述', 'url', '类型', '内容', '预览内容', '预览图']
        this.addArticle = this.addArticle.bind(this)
        this.updateArticle = this.updateArticle.bind(this)
        this.getArticleByMultipleConditionAndPage = this.getArticleByMultipleConditionAndPage.bind(this)
        this.getArticleCountByMultipleCondition = this.getArticleCountByMultipleCondition.bind(this)
    } 

    async addArticle({body}, res, next){ //添加文章

        try {
            let url = body.url

            if (!url)
                throw new Error(`你的url参数为空`)

            const urlObj = { url: url }

            let ans = await articleModel.findOne(urlObj)

            if (ans) { //存在相同的url的文章

                throw new Error(`已经存在url相同的文章，不能重复添加哦`)

            }

        } catch (err) {

            console.log(chalk.red(`亲，查询相同文章失败,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'QUERY_THE_SAME_ARTICLE',
                message: err.message
            })

            return
        }

        let flag1 = this.checkArticleParams(body,res) //校验前台参数值

        if(flag1){ //如果通过前台校验

            console.log('Successful')

            let { title, description, url, sort, type, content, hidden, preContent, preImg } = body

            const Article = {
                title, 
                description, 
                url, 
                sort, 
                type, 
                content, 
                hidden, 
                preContent, 
                preImg
            }

            try{

                const articlemodel = new articleModel(Article)

                await articlemodel.save()

                res.send({
                    status: 1,
                    type: 'ADD_ARTICLE',
                    message: '恭喜您，文章更新成功'
                })

            }catch(err){

                console.log(chalk.red(`亲，博客文章保存失败, 因为 ${err.message}`))

                res.send({
                    status: 0,
                    type: 'ADD_ARTICLE',
                    message: `亲，博客文章保存失败, 因为 ${err.message}`
                })

            }
            
        }
        
    }

    async deleteArticleByUrl({params}, res, next){ //通过url删除文章

        let { url } = params

        const urlObj = { url: url }

        try {

            if (!url)
                throw new Error(`你的url参数为空哦`)

            let ans = await articleModel.findOne(urlObj)

            if (!ans) { //不存在这篇文章

                throw new Error(`不存在这篇文章哦`)

            }

        } catch (err) {

            console.log(chalk.red(`亲，您的删除文章失败,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'DELETE_ARTICLE_BY_URL',
                message: err.message
            })

            return
        }

        try{

            const ans = await articleModel.remove(urlObj)

            res.send({
                status: 1,
                type: 'DELETE_ARTICLE_BY_URL',
                message: '恭喜您，已经成功删除了该文章'
            })

        }catch(err){

            console.log(chalk.red(`亲，您的文章删除失败,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'DELETE_ARTICLE_BY_URL',
                message: `亲，您的文章删除失败,因为 ${err.message}`
            })

        }
    }

    async updateArticle({ params, body }, res, next){ //通过url更新某些文章

        let {url} = params 

        const urlObj = {url: url}

        let flag1 = this.checkArticleParams(body, res) //校验前台参数值

        if (flag1){ //如果信息都有的话

            try{

                await articleModel.updateOne(urlObj,body)

                res.send({
                    status: 1,
                    type: 'UPDATE_ARTICLE',
                    message: '恭喜您，已经成功更新该文章'
                })

            }catch(err){

                console.log(chalk.red(`亲，您的文章更新失败,因为 ${err.message}`))

                res.send({
                    status: 0,
                    type: 'UPDATE_ARTICLE',
                    message: `亲，您的文章更新失败,因为 ${err.message}`
                })

            }
        }
    }

    async getArticleByMultipleConditionAndPage ({ query }, res, next){ //通过多个查询条件查询文章,title是模糊查询

        let { type, title, page, hidden } = query

        //console.log('page:',page,'type:',type)

        try{

            page = Number(page)

            if (!page || page <= 0)
                throw new Error('Page 不存在或者格式有问题')

            let queryCondition = this.getQueryCondition(type, title, hidden)

            const ans = await articleModel.find(queryCondition, { "_id": 0, "__v": 0 })
                .sort({ "sort": -1, "_id": -1 }).skip((--page) * 5).limit(5);

            res.send({
                status: 1,
                type: 'GET_ARTICLE_BY_MULTIPLE_CONDITION_AND_PAGE',
                message: ans
            })

        }catch(err){

            console.log(chalk.red(`亲，没有找到符合您条件的文章,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'GET_ARTICLE_BY_MULTIPLE_CONDITION_AND_PAGE',
                message: `亲，没有找到符合您条件的文章,因为 ${err.message}`
            })

        }

    }

    async getArticleCountByMultipleCondition({ query }, res, next) { //通过多个查询条件查询文章数目,title是模糊查询

        let { type, title, hidden } = query

        try{

            let queryCondition = this.getQueryCondition(type, title, hidden)

            const ans = await articleModel.find(queryCondition).count();

            res.send({
                status: 1,
                type: 'GET_ARTICLE_COUNT_BY_MULTIPLE_CONDITION',
                message: ans
            })

        }catch(err){

            console.log(chalk.red(`亲，没有找到您想要找的文章数目,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'GET_ARTICLE_COUNT_BY_MULTIPLE_CONDITION',
                message: `亲，没有找到您想要找的文章数目,因为 ${err.message}`
            })

        }
    }

    async getAllArticleType(req, res, next){ //获取所有文章类型

        try{

            let ans = await articleTypeModel.find({}, { "_id": 0, "__v": 0 })

            res.send({
                status: 1,
                type: 'GET_ALL_ARTICLE_TYPE',
                message: ans
            })

        }catch(err){

            console.log(chalk.red(`亲，查找所有文章类型失败,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'GET_ALL_ARTICLE_TYPE',
                message: `亲，查找所有文章类型失败,因为 ${err.message}`
            })

        }

    }

    async addArticleType({ body }, res, next) { //新增文章类型
        let { value } = body

        try{

            if (!value) //检查类型名
                throw new Error('类型名为空')

            let ans = await articleTypeModel.findOne({ value: value })

            if (ans)  //不存在这篇文章
                throw new Error(`已经存在这篇文章，不能重复添加哦`)
            
            const articleTypeModels = new articleTypeModel({value:value})

            await articleTypeModels.save() //保存文章类型

            res.send({
                status: 1,
                type: 'ADD_ARTICLE_TYPE',
                message: `亲，恭喜您新增文章类型成功！`
            })

        }catch(err){

            console.log(chalk.red(`亲，新增文章类型失败,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'ADD_ARTICLE_TYPE',
                message: `亲，新增文章类型失败,因为 ${err.message}`
            })

        }
    }

    async deleteArticleTypeByValue({params}, res, next){ //通过类型值删除类型

        let {value} =  params

        try{

            if(!value) //检查类型名
                throw new Error('类型名为空')

            let ans = await articleTypeModel.findOne({ value: value})

            if (!ans)  //不存在这篇文章
                throw new Error(`不存在该文章类型哦`)
            
            await articleTypeModel.remove({ value: value })

            res.send({
                status: 1,
                type: 'DELETE_ARTICLE_TYPE_BY_VALUE',
                message: `亲，恭喜您删除文章类型成功`
            })
            
        }catch(err){

            console.log(chalk.red(`亲，删除文章类型失败,因为 ${err.message}`))

            res.send({
                status: 0,
                type: 'DELETE_ARTICLE_TYPE_BY_VALUE',
                message: `亲，删除文章类型失败,因为 ${err.message}`
            })


        }

    }

    getQueryCondition(...obj){ //构建mongoose sql对象（查询条件)
        
        let QueryCondition = ['type', 'title','hidden']

        let ans = {}

        ans.$or =  []

        let queryContent = {}

        Array.from(obj).map((value, index)=>{

            if(value){

                if(index == 1){

                    var FuzzyQueryCondition = new RegExp(value,'i') //创建正则表达式

                    let obj = {}

                    obj.$regex = FuzzyQueryCondition //创建title的模糊查询

                    value = obj

                }
                queryContent[QueryCondition[index]] = value //构造查询对象

            }
                
        })

        ans.$or.push(queryContent)

        return ans

    }

    checkArticleParams(body, res){ //校验文章前台参数值

        this.articleParams = [] //初始化
        
        let { title, description, url, type, content, preContent, preImg } = body


        this.articleParams.push(title, description, url, type, content, preContent, preImg)



        try {

            this.articleParams.map((value,index)=>{

                if (!value)
                    throw new Error(`必须填写文章${this.articleParamsError[index]}`)

            })


        } catch (err) {

            console.log(chalk.red(`前台文章参数错误,${err.message}`))

            res.send({
                status: 0,
                type: 'ERROR_PARAMS',
                message: err.message
            })

            return false
        }

        return true
    }

}

export default new Article()